﻿// Imports System.Collections.Generic
// Imports System.Text
// Imports System.IO
// Imports System.Globalization
// Imports System.Text.RegularExpressions
// Imports System.ComponentModel
// Imports System.Net

// ''' FTP处理操作类
// Public Class FtpClient
// Implements Marmat.Data.BaseFileService


// #Region "私有属性"
// ''' <summary>
// ''' FTP请求对象
// ''' </summary>
// Private Request As FtpWebRequest = Nothing

// ''' <summary>
// ''' FTP响应对象
// ''' </summary>
// Private Response As FtpWebResponse = Nothing

// Private WithEvents FtpWebClient As FtpWebClient = New FtpWebClient

// ''' <summary>
// ''' 是否需要删除临时文件
// ''' </summary>
// Private _isDeleteTempFile As Boolean = False

// ''' <summary>
// ''' 异步上传所临时生成的文件
// ''' </summary>
// Private _UploadTempFile As String = ""

// ''' <summary>
// ''' 连接FTP服务器的代理服务
// ''' </summary>
// Private Property Proxy As WebProxy
// Get
// Return _Proxy
// End Get
// Set(ByVal value As WebProxy)
// _Proxy = value
// End Set
// End Property
// Private _Proxy As WebProxy = Nothing

// #End Region
// Public Function MergeHostAddress(ByVal Name As String) As String
// Dim Host As String = Me.Host.ToString
// If Host.EndsWith("/") OrElse Name.StartsWith("/") Then
// Return Host & Name
// Else
// Return Host & "/" & Name
// End If
// End Function

// #Region "属性信息"

// Public Property Name As String

// ''' <summary>
// ''' FTP服务器地址
// ''' </summary>
// Public Property Host As Uri
// Get
// If m_RootDir = "/" Then
// Return m_Uri
// Else
// Dim strUri As String = m_Uri.ToString
// If strUri.EndsWith("/") Then
// strUri = strUri.Substring(0, strUri.Length - 1)
// End If
// Return New Uri(strUri & Me.RootDir)
// End If
// End Get
// Set(ByVal value As Uri)
// If value.Scheme <> Uri.UriSchemeFtp Then
// Throw New Exception("Ftp 地址格式错误!")
// End If
// m_Uri = New Uri(value.GetLeftPart(UriPartial.Authority))
// m_RootDir = value.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// End Set
// End Property
// Private m_Uri As Uri

// Public ReadOnly Property Uri As Uri
// Get
// Return Me.m_Uri
// End Get
// End Property

// ''' <summary>
// ''' 当前工作目录
// ''' </summary>
// Public Property RootDir As String
// Get
// Return m_RootDir
// End Get
// Set(ByVal value As String)
// m_RootDir = value
// End Set
// End Property
// Private m_RootDir As String

// ''' <summary>
// ''' FTP登录用户
// ''' </summary>
// Public Property UserName As String
// Get
// Return m_UserName
// End Get
// Set(ByVal value As String)
// m_UserName = value
// End Set
// End Property
// Private m_UserName As String

// ''' <summary>
// ''' 错误信息
// ''' </summary>
// Public Property ErrorMsg As String
// Get
// Return _ErrorMsg
// End Get
// Set(ByVal value As String)
// _ErrorMsg = value
// End Set
// End Property
// Private _ErrorMsg As String

// ''' <summary>
// ''' FTP登录密码
// ''' </summary>
// Public Property Password As String
// Get
// Return _Password
// End Get
// Set(ByVal value As String)
// _Password = value
// End Set
// End Property
// Private _Password As String

// Public Property Encoding As Encoding = System.Text.Encoding.UTF8
// Public Property ImgService As System.Uri Implements BaseFileService.ImgService

// #End Region

// #Region "异步事件"

// ''' <summary>
// ''' 异步下载进度发生改变触发的事件
// ''' </summary>
// Public Event DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Implements BaseFileService.DownloadProgressChanged

// ''' <summary>
// ''' 异步下载文件完成之后触发的事件
// ''' </summary>
// Public Event DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Implements BaseFileService.DownloadFileCompleted

// ''' <summary>
// ''' 在异步数据下载操作完成时发生。
// ''' </summary>
// ''' <remarks></remarks>
// Public Event DownloadDataCompleted(sender As Object, e As DownloadDataCompletedEventArgs) Implements BaseFileService.DownloadDataCompleted

// ''' <summary>
// ''' 异步上传进度发生改变触发的事件
// ''' </summary>
// Public Event UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) Implements BaseFileService.UploadProgressChanged
// '
// ''' <summary>
// ''' 异步上传文件完成之后触发的事件
// ''' </summary>
// Public Event UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) Implements BaseFileService.UploadFileCompleted

// ''' <summary>
// ''' 在异步数据上载操作完成时发生。
// ''' </summary>
// ''' <remarks></remarks>
// Public Event UploadDataCompleted(sender As Object, e As UploadDataCompletedEventArgs) Implements BaseFileService.UploadDataCompleted
// #End Region

// #Region "构造析构函数"

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// ''' <param name="FtpUri">FTP地址</param>
// ''' <param name="strUserName">登录用户名</param>
// ''' <param name="strPassword">登录密码</param>
// Public Sub New(ByVal FtpUri As Uri, ByVal strUserName As String, ByVal strPassword As String)
// Me.m_Uri = New Uri(FtpUri.GetLeftPart(UriPartial.Authority))
// m_RootDir = FtpUri.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// Me.m_UserName = strUserName
// Me._Password = strPassword
// Me._Proxy = Nothing
// End Sub

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// ''' <param name="FtpUri">FTP地址</param>
// ''' <param name="strUserName">登录用户名</param>
// ''' <param name="strPassword">登录密码</param>
// ''' <param name="objProxy">连接代理</param>
// Public Sub New(ByVal FtpUri As Uri, ByVal strUserName As String, ByVal strPassword As String, ByVal objProxy As WebProxy)
// Me.m_Uri = New Uri(FtpUri.GetLeftPart(UriPartial.Authority))
// m_RootDir = FtpUri.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// Me.m_UserName = strUserName
// Me._Password = strPassword
// Me._Proxy = objProxy
// End Sub

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// Public Sub New()
// Me.m_UserName = "anonymous"
// 'anonymous匿名用户
// Me._Password = "@anonymous"
// '@anonymous
// Me.m_Uri = Nothing
// Me._Proxy = Nothing
// End Sub

// ''' <summary>
// ''' 析构函数
// ''' </summary>
// Protected Overrides Sub Finalize()
// Try
// If Response IsNot Nothing Then
// Response.Close()
// Response = Nothing
// End If
// If Request IsNot Nothing Then
// Request.Abort()
// Request = Nothing
// End If
// Finally
// MyBase.Finalize()
// End Try
// End Sub
// #End Region

// #Region "建立连接"
// '

// ''' <summary>
// ''' 建立FTP链接,返回响应对象
// ''' </summary>
// ''' <param name="uri">FTP地址</param>
// ''' <param name="FtpMathod">操作命令</param>
// Private Function Open(ByVal uri As Uri, ByVal FtpMathod As String) As FtpWebResponse
// Try
// Request = DirectCast(WebRequest.Create(uri), FtpWebRequest)
// Request.Method = FtpMathod
// Request.UseBinary = True
// Request.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Request.Proxy = Me.Proxy
// End If
// Return DirectCast(Request.GetResponse, FtpWebResponse)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// '

// ''' <summary>
// ''' 建立FTP链接,返回请求对象
// ''' </summary>
// ''' <param name="uri">FTP地址</param>
// ''' <param name="FtpMathod">操作命令</param>
// Private Function OpenRequest(ByVal uri As Uri, ByVal FtpMathod As String) As FtpWebRequest
// Try
// Request = DirectCast(WebRequest.Create(uri), FtpWebRequest)
// Request.Method = FtpMathod
// Request.UseBinary = True
// Request.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Request.Proxy = Me.Proxy
// End If
// Return Request
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "下载文件"

// ''' <summary>
// ''' 从FTP服务器下载文件，使用与远程文件同名的文件名来保存文件
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalPath">本地路径</param>
// Public Overloads Function Download(ByVal RemoteFileName As String, ByVal LocalPath As String) As Boolean Implements BaseFileService.Download
// Return Download(RemoteFileName, LocalPath, RemoteFileName)
// End Function
// '

// ''' <summary>
// ''' 从FTP服务器下载文件，指定本地路径和本地文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalPath">本地路径</param>
// ''' <param name="LocalFileName">保存本地的文件名</param>
// Public Overloads Function Download(ByVal RemoteFileName As String, ByVal LocalPath As String, ByVal LocalFileName As String) As Boolean
// Dim bt As Byte() = Nothing
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(LocalFileName) OrElse Not IsValidPathChars(LocalPath) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not Directory.Exists(LocalPath) Then
// Throw New Exception("本地文件路径不存在!")
// End If

// Dim LocalFullPath As String = Path.Combine(LocalPath, LocalFileName)
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If
// bt = Download(RemoteFileName)
// If bt IsNot Nothing Then
// Dim stream As New FileStream(LocalFullPath, FileMode.Create)
// stream.Write(bt, 0, bt.Length)
// stream.Flush()
// stream.Close()
// Return True
// Else
// Return False
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从FTP服务器下载文件，返回文件二进制数据
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Overloads Function Download(ByVal RemoteFileName As String) As Byte()
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// Response = Open(New Uri(Me.Host.ToString() & RemoteFileName), WebRequestMethods.Ftp.DownloadFile)
// Dim Reader As Stream = Response.GetResponseStream()

// Dim mem As New MemoryStream(1024 * 500)
// Dim buffer As Byte() = New Byte(1023) {}
// Dim bytesRead As Integer = 0
// Dim TotalByteRead As Integer = 0
// While True
// bytesRead = Reader.Read(buffer, 0, buffer.Length)
// TotalByteRead += bytesRead
// If bytesRead = 0 Then
// Exit While
// End If
// mem.Write(buffer, 0, bytesRead)
// End While
// If mem.Length > 0 Then
// Return mem.ToArray()
// Else
// Return Nothing
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "异步下载文件"
// '

// ''' <summary>
// ''' 从FTP服务器异步下载文件，指定本地路径和本地文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>        
// ''' <param name="LocalPath">保存文件的本地路径,后面带有"\"</param>
// ''' <param name="LocalFileName">保存本地的文件名</param>
// Public Overloads Sub DownloadAsync(ByVal RemoteFileName As String, ByVal LocalPath As String, ByVal LocalFileName As String)
// Dim bt As Byte() = Nothing
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(LocalFileName) OrElse Not IsValidPathChars(LocalPath) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not Directory.Exists(LocalPath) Then
// Throw New Exception("本地文件路径不存在!")
// End If

// Dim LocalFullPath As String = Path.Combine(LocalPath, LocalFileName)
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If

// Me.DownloadAsync(RemoteFileName, LocalFullPath)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// ''' <summary>
// ''' 从FTP服务器异步下载文件，指定本地完整路径文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalFullPath">本地完整路径文件名</param>
// Public Overloads Sub DownloadAsync(ByVal RemoteFileName As String, ByVal LocalFullPath As String) Implements BaseFileService.DownloadAsync
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If
// 'Dim client As New MyWebClient()
// 'AddHandler client.DownloadProgressChanged, New System.Net.DownloadProgressChangedEventHandler(AddressOf client_DownloadProgressChanged)
// 'AddHandler client.DownloadFileCompleted, New System.ComponentModel.AsyncCompletedEventHandler(AddressOf client_DownloadFileCompleted)
// Me.FtpWebClient.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Me.FtpWebClient.Proxy = Me.Proxy
// End If
// Me.FtpWebClient.DownloadFileAsync(New Uri(Me.Host.ToString & RemoteFileName), LocalFullPath)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// Private Sub FtpWebClient_UploadProgressChanged(sender As Object, e As Net.UploadProgressChangedEventArgs) Handles FtpWebClient.UploadProgressChanged
// Dim info As New UploadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// info.m_BytesReceived = e.BytesReceived
// info.m_BytesSent = e.BytesSent
// info.m_ProgressPercentage = e.ProgressPercentage
// info.m_TotalBytesToReceive = e.TotalBytesToReceive
// info.m_TotalBytesToReceive = e.TotalBytesToReceive
// info.m_TotalBytesToSend = e.TotalBytesToSend
// RaiseEvent UploadProgressChanged(Me, info)
// End Sub
// Private Sub FtpWebClient_UploadDataCompleted(sender As Object, e As Net.UploadDataCompletedEventArgs) Handles FtpWebClient.UploadDataCompleted
// Dim info As New UploadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent UploadDataCompleted(Me, info)
// End Sub

// Private Sub FtpWebClient_UploadFileCompleted(sender As Object, e As Net.UploadFileCompletedEventArgs) Handles FtpWebClient.UploadFileCompleted
// Dim info As New UploadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent UploadDataCompleted(Me, info)
// End Sub

// Private Sub FtpWebClient_DownloadDataCompleted(sender As Object, e As Net.DownloadDataCompletedEventArgs) Handles FtpWebClient.DownloadDataCompleted
// Dim info As New DownloadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent DownloadDataCompleted(sender, info)
// End Sub

// ''' <summary>
// ''' 异步下载文件完成之后触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">数据信息对象</param>
// Private Sub client_DownloadFileCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles FtpWebClient.DownloadFileCompleted
// Dim Args As New AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState)
// RaiseEvent DownloadFileCompleted(sender, Args)
// End Sub

// ''' <summary>
// ''' 异步下载进度发生改变触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">进度信息对象</param>
// Private Sub client_DownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles FtpWebClient.DownloadProgressChanged
// Dim Args As New DownloadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// Args.m_BytesReceived = e.BytesReceived
// Args.m_TotalBytesToReceive = e.TotalBytesToReceive
// RaiseEvent DownloadProgressChanged(sender, Args)
// End Sub

// ''' <summary>
// ''' 生成一个用HTTP GET方法访问指定图片大小的Uri
// ''' </summary>
// ''' <param name="FileName">文件服务器的文件名</param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Public Function GeneratePresignedUri(ByVal FileName As String, ByVal Width As Integer, ByVal Height As Integer) As Uri Implements BaseFileService.GeneratePresignedUri
// End Function
// #End Region

// #Region "上传文件"
// '
// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String) As Boolean
// Return Upload(LocalFullPath, Path.GetFileName(LocalFullPath), False)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal RemoteFileName As String) As Boolean Implements BaseFileService.Upload
// Return Me.Upload(LocalFullPath, RemoteFileName, False)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal OverWriteRemoteFile As Boolean) As Boolean
// Return Upload(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(Path.GetFileName(LocalFullPath)) OrElse Not IsValidPathChars(Path.GetDirectoryName(LocalFullPath)) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If File.Exists(LocalFullPath) Then
// Dim Stream As New FileStream(LocalFullPath, FileMode.Open, FileAccess.Read)
// Dim bt As Byte() = New Byte(Stream.Length - 1) {}
// Stream.Read(bt, 0, CType(Stream.Length, Int32))
// '注意，因为Int32的最大限制，最大上传文件只能是大约2G多一点
// Stream.Close()
// Return Me.Upload(bt, RemoteFileName, OverWriteRemoteFile)
// Else
// Throw New Exception("本地文件不存在!")
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">上传的二进制数据</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Function Upload(ByVal FileBytes As Byte(), ByVal RemoteFileName As String) As Boolean
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// Return Upload(FileBytes, RemoteFileName, False)
// End Function
// '

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">文件二进制内容</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal FileBytes As Byte(), ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean) As Boolean

// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名！")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.UploadFile)
// Dim requestStream As Stream = Request.GetRequestStream
// Dim mem As New MemoryStream(FileBytes)

// Dim buffer As Byte() = New Byte(1023) {}
// Dim bytesRead As Integer = 0
// Dim TotalRead As Integer = 0
// While True
// bytesRead = mem.Read(buffer, 0, buffer.Length)
// If bytesRead = 0 Then
// Exit While
// End If
// TotalRead += bytesRead
// requestStream.Write(buffer, 0, bytesRead)
// End While
// requestStream.Close()
// Response = DirectCast(Request.GetResponse(), FtpWebResponse)
// mem.Close()
// mem.Dispose()
// FileBytes = Nothing
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "异步上传文件"
// '
// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String)
// UploadAsync(LocalFullPath, Path.GetFileName(LocalFullPath), False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal OverWriteRemoteFile As Boolean)
// UploadAsync(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal RemoteFileName As String) Implements BaseFileService.UploadAsync
// UploadAsync(LocalFullPath, RemoteFileName, False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean)
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(Path.GetFileName(LocalFullPath)) OrElse Not IsValidPathChars(Path.GetDirectoryName(LocalFullPath)) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// If File.Exists(LocalFullPath) Then
// 'Dim client As New MyWebClient()

// 'AddHandler client.UploadProgressChanged, New System.Net.UploadProgressChangedEventHandler(AddressOf client_UploadProgressChanged)
// 'AddHandler client.UploadFileCompleted, New System.Net.UploadFileCompletedEventHandler(AddressOf client_UploadFileCompleted)
// 'client.Credentials = New System.Net.NetworkCredential(Me.UserName, Me.Password)
// 'If Me.Proxy IsNot Nothing Then
// '    client.Proxy = Me.Proxy
// 'End If
// 'Dim Uri As New Uri(Me.Host.ToString & RemoteFileName)
// 'client.UploadFileAsync(Uri, LocalFullPath)
// Me.FtpWebClient.Credentials = New System.Net.NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Me.FtpWebClient.Proxy = Me.Proxy
// End If
// Dim Uri As New Uri(Me.Host.ToString & RemoteFileName)
// Me.FtpWebClient.UploadFileAsync(Uri, LocalFullPath)
// Else
// Throw New Exception("本地文件不存在!")
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">上传的二进制数据</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Sub UploadAsync(ByVal FileBytes As Byte(), ByVal RemoteFileName As String)
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// UploadAsync(FileBytes, RemoteFileName, False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">文件二进制内容</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal FileBytes As Byte(), ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean)
// Try

// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名！")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// Dim TempPath As String = System.Environment.GetFolderPath(Environment.SpecialFolder.Templates)
// If Not TempPath.EndsWith("\") Then
// TempPath += "\"
// End If
// Dim TempFile As String = TempPath & Path.GetRandomFileName()
// TempFile = Path.ChangeExtension(TempFile, Path.GetExtension(RemoteFileName))
// Dim Stream As New FileStream(TempFile, FileMode.CreateNew, FileAccess.Write)
// Stream.Write(FileBytes, 0, FileBytes.Length)
// '注意，因为Int32的最大限制，最大上传文件只能是大约2G多一点
// Stream.Flush()
// Stream.Close()
// Stream.Dispose()
// _isDeleteTempFile = True
// _UploadTempFile = TempFile
// FileBytes = Nothing



// UploadAsync(TempFile, RemoteFileName, OverWriteRemoteFile)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// '

// ''' <summary>
// ''' 异步上传文件完成之后触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">数据信息对象</param>
// Private Sub client_UploadFileCompleted(ByVal sender As Object, ByVal e As System.Net.UploadFileCompletedEventArgs)
// If _isDeleteTempFile Then
// If File.Exists(_UploadTempFile) Then
// File.SetAttributes(_UploadTempFile, FileAttributes.Normal)
// File.Delete(_UploadTempFile)
// End If
// _isDeleteTempFile = False
// End If
// Dim args As New UploadFileCompletedEventArgs(e.Error, e.Cancelled, e.UserState)
// args.m_Result = e.Result
// RaiseEvent UploadFileCompleted(sender, args)
// End Sub

// '

// ''' <summary>
// ''' 异步上传进度发生改变触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">进度信息对象</param>
// Private Sub client_UploadProgressChanged(ByVal sender As Object, ByVal e As System.Net.UploadProgressChangedEventArgs)
// Dim args As New UploadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// args.m_BytesSent = e.BytesSent
// args.m_TotalBytesToReceive = e.TotalBytesToReceive
// args.m_TotalBytesToSend = e.TotalBytesToSend
// RaiseEvent UploadProgressChanged(sender, args)
// End Sub
// #End Region

// #Region "删除文件"
// ''' <summary>
// ''' 从FTP服务器上面删除一个文件
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Function Delete(ByVal RemoteFileName As String) As Boolean Implements BaseFileService.Delete
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("文件名非法！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.DeleteFile)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// Return False
// End Try
// Return True
// End Function
// #End Region


// ''' <summary>
// ''' 生成一个用HTTP GET方法访问文件的Uri
// ''' </summary>
// ''' <param name="FileName">文件服务器的文件名</param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Public Function GeneratePresignedUri(ByVal FileName As String) As Uri Implements BaseFileService.GeneratePresignedUri
// Dim txt As String = Me.Host.OriginalString
// If txt.StartsWith("ftp://") Then
// txt = txt.Remove(0, 6)
// End If
// Return New Uri(String.Format("ftp://{0}:{1}@{2}/{3}", Me.UserName, Me.Password, txt, FileName))
// End Function

// #Region "列出目录文件信息"
// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有文件和目录
// ''' </summary>
// Public Function ListFilesAndDirectories() As FTPFileStruct()
// Response = Open(Me.Host, WebRequestMethods.Ftp.ListDirectoryDetails)
// Dim stream As New StreamReader(Response.GetResponseStream(), Me.Encoding)
// Dim Datastring As String = stream.ReadToEnd()
// Dim list As FTPFileStruct() = GetList(Datastring)
// Return list
// End Function
// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有文件
// ''' </summary>
// Public Function ListFiles() As FTPFileStruct()
// Dim listAll As FTPFileStruct() = ListFilesAndDirectories()
// Dim listFile As New List(Of FTPFileStruct)()
// For Each file As FTPFileStruct In listAll
// If Not file.IsDirectory Then
// listFile.Add(file)
// End If
// Next
// Return listFile.ToArray()
// End Function

// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有的目录
// ''' </summary>
// Public Function ListDirectories() As FTPFileStruct()
// Dim listAll As FTPFileStruct() = ListFilesAndDirectories()
// Dim listDirectory As New List(Of FTPFileStruct)()
// For Each file As FTPFileStruct In listAll
// If file.IsDirectory Then
// listDirectory.Add(file)
// End If
// Next
// Return listDirectory.ToArray()
// End Function
// '

// ''' <summary>
// ''' 获得文件和目录列表
// ''' </summary>
// ''' <param name="datastring">FTP返回的列表字符信息</param>
// Private Function GetList(ByVal datastring As String) As FTPFileStruct()
// Dim myListArray As New List(Of FTPFileStruct)()
// Dim dataRecords As String() = datastring.Split(ControlChars.Lf)
// Dim _directoryListStyle As FTPListStyle = GuessFileListStyle(dataRecords)
// For Each s As String In dataRecords
// If _directoryListStyle <> FTPListStyle.Unknown AndAlso s <> "" Then
// Dim f As New FTPFileStruct()
// f.Name = ".."
// Select Case _directoryListStyle
// Case FTPListStyle.UnixStyle
// f = ParseFTPFileStructFromUnixStyleRecord(s)
// Exit Select
// Case FTPListStyle.WindowsStyle
// f = ParseFTPFileStructFromWindowsStyleRecord(s)
// Exit Select
// End Select
// If Not (f.Name = "." OrElse f.Name = "..") Then
// myListArray.Add(f)
// End If
// End If
// Next
// Return myListArray.ToArray()
// End Function

// '

// ''' <summary>
// ''' 从Windows格式中返回文件信息
// ''' </summary>
// ''' <param name="Record">文件信息</param>
// Private Function ParseFTPFileStructFromWindowsStyleRecord(ByVal Record As String) As FTPFileStruct
// Dim f As New FTPFileStruct()
// Dim processstr As String = Record.Trim()
// Dim dateStr As String = processstr.Substring(0, 8)
// processstr = (processstr.Substring(8, processstr.Length - 8)).Trim()
// Dim timeStr As String = processstr.Substring(0, 7)
// processstr = (processstr.Substring(7, processstr.Length - 7)).Trim()
// Dim myDTFI As DateTimeFormatInfo = New CultureInfo("en-US", False).DateTimeFormat
// myDTFI.ShortTimePattern = "t"
// f.CreateTime = DateTime.Parse(dateStr & " " & timeStr, myDTFI)
// If processstr.Substring(0, 5) = "<DIR>" Then
// f.IsDirectory = True
// processstr = (processstr.Substring(5, processstr.Length - 5)).Trim()
// Else
// 'Dim strs As String() = processstr.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
// ' true);
// Dim IndexOf As Integer = processstr.IndexOf(" ")
// processstr = processstr.Substring(IndexOf + 1)
// 'processstr = strs(1)
// f.IsDirectory = False
// End If
// f.Name = processstr
// Return f
// End Function

// ''' <summary>
// ''' 判断文件列表的方式Window方式还是Unix方式
// ''' </summary>
// ''' <param name="recordList">文件信息列表</param>
// Private Function GuessFileListStyle(ByVal recordList As String()) As FTPListStyle
// For Each s As String In recordList
// If s.Length > 10 AndAlso Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)") Then
// Return FTPListStyle.UnixStyle
// ElseIf s.Length > 8 AndAlso Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]") Then
// Return FTPListStyle.WindowsStyle
// End If
// Next
// Return FTPListStyle.Unknown
// End Function

// ''' <summary>
// ''' 从Unix格式中返回文件信息
// ''' </summary>
// ''' <param name="Record">文件信息</param>
// Private Function ParseFTPFileStructFromUnixStyleRecord(ByVal Record As String) As FTPFileStruct
// Dim f As New FTPFileStruct()
// Dim processstr As String = Record.Trim()
// f.Flags = processstr.Substring(0, 10)
// f.IsDirectory = (f.Flags(0) = "d"c)
// processstr = (processstr.Substring(11)).Trim()
// _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// '跳过一部分
// f.Owner = _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// f.Group = _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// '跳过一部分
// Dim yearOrTime As String = processstr.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)(2)
// If yearOrTime.IndexOf(":") >= 0 Then
// 'time
// processstr = processstr.Replace(yearOrTime, DateTime.Now.Year.ToString())
// End If
// f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(processstr, " "c, 8))
// f.Name = processstr
// '最后就是名称
// Return f
// End Function

// ''' <summary>
// ''' 按照一定的规则进行字符串截取
// ''' </summary>
// ''' <param name="s">截取的字符串</param>
// ''' <param name="c">查找的字符</param>
// ''' <param name="startIndex">查找的位置</param>
// Private Function _cutSubstringFromStringWithTrim(ByRef s As String, ByVal c As Char, ByVal startIndex As Integer) As String
// Dim pos1 As Integer = s.IndexOf(c, startIndex)
// Dim retString As String = s.Substring(0, pos1)
// s = (s.Substring(pos1)).Trim()
// Return retString
// End Function
// #End Region

// #Region "目录或文件存在的判断"

// ''' <summary>
// ''' 判断当前目录下指定的子目录是否存在
// ''' </summary>
// ''' <param name="RemoteDirectoryName">指定的目录名</param>
// Public Function DirectoryExist(ByVal RemoteDirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(RemoteDirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// Dim listDir As FTPFileStruct() = ListDirectories()
// For Each dir As FTPFileStruct In listDir
// If dir.Name = RemoteDirectoryName Then
// Return True
// End If
// Next
// Return False
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 判断一个远程文件是否存在服务器当前目录下面
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Function FileExist(ByVal RemoteFileName As String) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("文件名非法！")
// End If
// Dim listFile As FTPFileStruct() = ListFiles()
// For Each file As FTPFileStruct In listFile
// If file.Name = RemoteFileName Then
// Return True
// End If
// Next
// Return False
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region




// #Region "重命名文件"

// ''' <summary>
// ''' 更改一个文件的名称或一个目录的名称
// ''' </summary>
// ''' <param name="RemoteFileName">原始文件或目录名称</param>
// ''' <param name="NewFileName">新的文件或目录的名称</param>
// Public Function ReName(ByVal RemoteFileName As String, ByVal NewFileName As String) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(NewFileName) Then
// Throw New Exception("文件名非法！")
// End If
// If RemoteFileName = NewFileName Then
// Return True
// End If
// If FileExist(RemoteFileName) OrElse DirectoryExist(RemoteFileName) Then
// Request = OpenRequest(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.Rename)
// Request.RenameTo = NewFileName

// Response = DirectCast(Request.GetResponse(), FtpWebResponse)
// Else
// Throw New Exception("文件在服务器上不存在！")
// End If
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "拷贝、移动文件"

// ''' <summary>
// ''' 把当前目录下面的一个文件拷贝到服务器上面另外的目录中，注意，拷贝文件之后，当前工作目录还是文件原来所在的目录
// ''' </summary>
// ''' <param name="RemoteFile">当前目录下的文件名</param>
// ''' <param name="DirectoryName">新目录名称。
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ；
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// ''' <returns></returns>
// Public Function CopyFileToAnotherDirectory(ByVal RemoteFile As String, ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkDir As String = Me.RootDir
// Try
// Dim bt As Byte() = Download(RemoteFile)
// GotoDirectory(DirectoryName)
// Dim Success As Boolean = Upload(bt, RemoteFile, False)
// Me.RootDir = CurrentWorkDir
// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkDir
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 把当前目录下面的一个文件移动到服务器上面另外的目录中，注意，移动文件之后，当前工作目录还是文件原来所在的目录
// ''' </summary>
// ''' <param name="RemoteFile">当前目录下的文件名</param>
// ''' <param name="DirectoryName">新目录名称。
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ；
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// ''' <returns></returns>
// Public Function MoveFileToAnotherDirectory(ByVal RemoteFile As String, ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkDir As String = Me.RootDir
// Try
// If DirectoryName = "" Then
// Return False
// End If
// If Not DirectoryName.StartsWith("/") Then
// DirectoryName = "/" & DirectoryName
// End If
// If Not DirectoryName.EndsWith("/") Then
// DirectoryName += "/"
// End If
// Dim Success As Boolean = ReName(RemoteFile, DirectoryName & RemoteFile)
// Me.RootDir = CurrentWorkDir
// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkDir
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "建立、删除子目录"

// ''' <summary>
// ''' 在FTP服务器上当前工作目录建立一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Public Function MakeDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// If DirectoryExist(DirectoryName) Then
// Throw New Exception("服务器上面已经存在同名的文件名或目录名！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(DirectoryName)), WebRequestMethods.Ftp.MakeDirectory)
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录中删除一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Public Function RemoveDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// If Not DirectoryExist(DirectoryName) Then
// Throw New Exception("服务器上面不存在指定的文件名或目录名！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(DirectoryName)), WebRequestMethods.Ftp.RemoveDirectory)
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "文件、目录名称有效性判断"

// ''' <summary>
// ''' 判断目录名中字符是否合法
// ''' </summary>
// ''' <param name="DirectoryName">目录名称</param>
// Public Function IsValidPathChars(ByVal DirectoryName As String) As Boolean
// Dim invalidPathChars As Char() = Path.GetInvalidPathChars()
// Dim DirChar As Char() = DirectoryName.ToCharArray()
// For Each C As Char In DirChar
// If Array.BinarySearch(invalidPathChars, C) >= 0 Then
// Return False
// End If
// Next
// Return True
// End Function

// ''' <summary>
// ''' 判断文件名中字符是否合法
// ''' </summary>
// ''' <param name="FileName">文件名称</param>
// Public Function IsValidFileChars(ByVal FileName As String) As Boolean
// Dim invalidFileChars As Char() = Path.GetInvalidFileNameChars()
// Dim NameChar As Char() = FileName.ToCharArray()
// For Each C As Char In NameChar
// If Array.BinarySearch(invalidFileChars, C) >= 0 Then
// Return False
// End If
// Next
// Return True
// End Function
// #End Region

// #Region "目录切换操作"

// ''' <summary>
// ''' 进入一个目录
// ''' </summary>
// ''' <param name="DirectoryName">
// ''' 新目录的名字。 
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ； 
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// Public Function GotoDirectory(ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkPath As String = Me.RootDir
// Try
// DirectoryName = DirectoryName.Replace("\", "/")
// Dim DirectoryNames As String() = DirectoryName.Split(New Char() {"/"c})
// If DirectoryNames(0) = "." Then
// Me.RootDir = "/"
// If DirectoryNames.Length = 1 Then
// Return True
// End If
// Array.Clear(DirectoryNames, 0, 1)
// End If
// Dim Success As Boolean = False
// For Each dir As String In DirectoryNames
// If dir IsNot Nothing Then
// Success = EnterOneSubDirectory(dir)
// If Not Success Then
// Me.RootDir = CurrentWorkPath
// Return False
// End If
// End If
// Next

// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkPath
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录进入一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Private Function EnterOneSubDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If DirectoryName.IndexOf("/") >= 0 OrElse Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法!")
// End If
// If DirectoryName.Length > 0 AndAlso DirectoryExist(DirectoryName) Then
// If Not DirectoryName.EndsWith("/") Then
// DirectoryName += "/"
// End If
// m_RootDir += DirectoryName
// Return True
// Else
// Return False
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录往上一级目录
// ''' </summary>
// Public Function ComeoutDirectory() As Boolean
// If m_RootDir = "/" Then
// ErrorMsg = "当前目录已经是根目录！"
// Throw New Exception("当前目录已经是根目录！")
// End If
// Dim sp As Char() = New Char(0) {"/"c}

// Dim strDir As String() = m_RootDir.Split(sp, StringSplitOptions.RemoveEmptyEntries)
// If strDir.Length = 1 Then
// m_RootDir = "/"
// Else
// m_RootDir = [String].Join("/", strDir, 0, strDir.Length - 1)
// End If
// Return True
// End Function
// #End Region

// #Region "表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。"
// ''' <summary>
// ''' 表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。
// ''' </summary>
// ''' <param name="FileName"></param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Friend Function GetFileSize(ByVal FileName As String) As Integer
// Dim ftp As FtpWebRequest
// Dim Uri As String = "ftp://" & Me.Host.Host & ":" & 21 & "/" & FileName
// ftp = DirectCast(FtpWebRequest.Create(New Uri(Uri)), FtpWebRequest)
// ftp.Credentials = New NetworkCredential(UserName, Password)
// ftp.Method = WebRequestMethods.Ftp.GetFileSize
// Dim Size As Integer
// Try
// Dim ftpresponse As FtpWebResponse = DirectCast(ftp.GetResponse(), FtpWebResponse)
// Size = ftpresponse.ContentLength
// Return Size
// Catch ex As WebException
// Dim wr As FtpWebResponse = DirectCast(ex.Response, FtpWebResponse)
// Catch ex As Exception
// Windows.Forms.MessageBox.Show(ex.ToString)
// End Try
// Return Size
// End Function
// #End Region

// '#Region "重载WebClient，支持FTP进度"
// '    Friend Class MyWebClient
// '        Inherits WebClient
// '        Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
// '            Dim req As FtpWebRequest = DirectCast(MyBase.GetWebRequest(address), FtpWebRequest)
// '            req.UsePassive = False
// '            Return req
// '        End Function
// '    End Class
// '#End Region

// End Class
// Imports System.Collections.Generic
// Imports System.Text
// Imports System.IO
// Imports System.Globalization
// Imports System.Text.RegularExpressions
// Imports System.ComponentModel
// Imports System.Net

// ''' FTP处理操作类
// Public Class FtpClient
// Implements Marmat.Data.BaseFileService


// #Region "私有属性"
// ''' <summary>
// ''' FTP请求对象
// ''' </summary>
// Private Request As FtpWebRequest = Nothing

// ''' <summary>
// ''' FTP响应对象
// ''' </summary>
// Private Response As FtpWebResponse = Nothing

// Private WithEvents FtpWebClient As FtpWebClient = New FtpWebClient

// ''' <summary>
// ''' 是否需要删除临时文件
// ''' </summary>
// Private _isDeleteTempFile As Boolean = False

// ''' <summary>
// ''' 异步上传所临时生成的文件
// ''' </summary>
// Private _UploadTempFile As String = ""

// ''' <summary>
// ''' 连接FTP服务器的代理服务
// ''' </summary>
// Private Property Proxy As WebProxy
// Get
// Return _Proxy
// End Get
// Set(ByVal value As WebProxy)
// _Proxy = value
// End Set
// End Property
// Private _Proxy As WebProxy = Nothing

// #End Region
// Public Function MergeHostAddress(ByVal Name As String) As String
// Dim Host As String = Me.Host.ToString
// If Host.EndsWith("/") OrElse Name.StartsWith("/") Then
// Return Host & Name
// Else
// Return Host & "/" & Name
// End If
// End Function

// #Region "属性信息"

// Public Property Name As String

// ''' <summary>
// ''' FTP服务器地址
// ''' </summary>
// Public Property Host As Uri
// Get
// If m_RootDir = "/" Then
// Return m_Uri
// Else
// Dim strUri As String = m_Uri.ToString
// If strUri.EndsWith("/") Then
// strUri = strUri.Substring(0, strUri.Length - 1)
// End If
// Return New Uri(strUri & Me.RootDir)
// End If
// End Get
// Set(ByVal value As Uri)
// If value.Scheme <> Uri.UriSchemeFtp Then
// Throw New Exception("Ftp 地址格式错误!")
// End If
// m_Uri = New Uri(value.GetLeftPart(UriPartial.Authority))
// m_RootDir = value.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// End Set
// End Property
// Private m_Uri As Uri

// Public ReadOnly Property Uri As Uri
// Get
// Return Me.m_Uri
// End Get
// End Property

// ''' <summary>
// ''' 当前工作目录
// ''' </summary>
// Public Property RootDir As String
// Get
// Return m_RootDir
// End Get
// Set(ByVal value As String)
// m_RootDir = value
// End Set
// End Property
// Private m_RootDir As String

// ''' <summary>
// ''' FTP登录用户
// ''' </summary>
// Public Property UserName As String
// Get
// Return m_UserName
// End Get
// Set(ByVal value As String)
// m_UserName = value
// End Set
// End Property
// Private m_UserName As String

// ''' <summary>
// ''' 错误信息
// ''' </summary>
// Public Property ErrorMsg As String
// Get
// Return _ErrorMsg
// End Get
// Set(ByVal value As String)
// _ErrorMsg = value
// End Set
// End Property
// Private _ErrorMsg As String

// ''' <summary>
// ''' FTP登录密码
// ''' </summary>
// Public Property Password As String
// Get
// Return _Password
// End Get
// Set(ByVal value As String)
// _Password = value
// End Set
// End Property
// Private _Password As String

// Public Property Encoding As Encoding = System.Text.Encoding.UTF8
// Public Property ImgService As System.Uri Implements BaseFileService.ImgService

// #End Region

// #Region "异步事件"

// ''' <summary>
// ''' 异步下载进度发生改变触发的事件
// ''' </summary>
// Public Event DownloadProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs) Implements BaseFileService.DownloadProgressChanged

// ''' <summary>
// ''' 异步下载文件完成之后触发的事件
// ''' </summary>
// Public Event DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs) Implements BaseFileService.DownloadFileCompleted

// ''' <summary>
// ''' 在异步数据下载操作完成时发生。
// ''' </summary>
// ''' <remarks></remarks>
// Public Event DownloadDataCompleted(sender As Object, e As DownloadDataCompletedEventArgs) Implements BaseFileService.DownloadDataCompleted

// ''' <summary>
// ''' 异步上传进度发生改变触发的事件
// ''' </summary>
// Public Event UploadProgressChanged(sender As Object, e As UploadProgressChangedEventArgs) Implements BaseFileService.UploadProgressChanged
// '
// ''' <summary>
// ''' 异步上传文件完成之后触发的事件
// ''' </summary>
// Public Event UploadFileCompleted(sender As Object, e As UploadFileCompletedEventArgs) Implements BaseFileService.UploadFileCompleted

// ''' <summary>
// ''' 在异步数据上载操作完成时发生。
// ''' </summary>
// ''' <remarks></remarks>
// Public Event UploadDataCompleted(sender As Object, e As UploadDataCompletedEventArgs) Implements BaseFileService.UploadDataCompleted
// #End Region

// #Region "构造析构函数"

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// ''' <param name="FtpUri">FTP地址</param>
// ''' <param name="strUserName">登录用户名</param>
// ''' <param name="strPassword">登录密码</param>
// Public Sub New(ByVal FtpUri As Uri, ByVal strUserName As String, ByVal strPassword As String)
// Me.m_Uri = New Uri(FtpUri.GetLeftPart(UriPartial.Authority))
// m_RootDir = FtpUri.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// Me.m_UserName = strUserName
// Me._Password = strPassword
// Me._Proxy = Nothing
// End Sub

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// ''' <param name="FtpUri">FTP地址</param>
// ''' <param name="strUserName">登录用户名</param>
// ''' <param name="strPassword">登录密码</param>
// ''' <param name="objProxy">连接代理</param>
// Public Sub New(ByVal FtpUri As Uri, ByVal strUserName As String, ByVal strPassword As String, ByVal objProxy As WebProxy)
// Me.m_Uri = New Uri(FtpUri.GetLeftPart(UriPartial.Authority))
// m_RootDir = FtpUri.AbsolutePath
// If Not m_RootDir.EndsWith("/") Then
// m_RootDir += "/"
// End If
// Me.m_UserName = strUserName
// Me._Password = strPassword
// Me._Proxy = objProxy
// End Sub

// ''' <summary>
// ''' 构造函数
// ''' </summary>
// Public Sub New()
// Me.m_UserName = "anonymous"
// 'anonymous匿名用户
// Me._Password = "@anonymous"
// '@anonymous
// Me.m_Uri = Nothing
// Me._Proxy = Nothing
// End Sub

// ''' <summary>
// ''' 析构函数
// ''' </summary>
// Protected Overrides Sub Finalize()
// Try
// If Response IsNot Nothing Then
// Response.Close()
// Response = Nothing
// End If
// If Request IsNot Nothing Then
// Request.Abort()
// Request = Nothing
// End If
// Finally
// MyBase.Finalize()
// End Try
// End Sub
// #End Region

// #Region "建立连接"
// '

// ''' <summary>
// ''' 建立FTP链接,返回响应对象
// ''' </summary>
// ''' <param name="uri">FTP地址</param>
// ''' <param name="FtpMathod">操作命令</param>
// Private Function Open(ByVal uri As Uri, ByVal FtpMathod As String) As FtpWebResponse
// Try
// Request = DirectCast(WebRequest.Create(uri), FtpWebRequest)
// Request.Method = FtpMathod
// Request.UseBinary = True
// Request.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Request.Proxy = Me.Proxy
// End If
// Return DirectCast(Request.GetResponse, FtpWebResponse)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// '

// ''' <summary>
// ''' 建立FTP链接,返回请求对象
// ''' </summary>
// ''' <param name="uri">FTP地址</param>
// ''' <param name="FtpMathod">操作命令</param>
// Private Function OpenRequest(ByVal uri As Uri, ByVal FtpMathod As String) As FtpWebRequest
// Try
// Request = DirectCast(WebRequest.Create(uri), FtpWebRequest)
// Request.Method = FtpMathod
// Request.UseBinary = True
// Request.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Request.Proxy = Me.Proxy
// End If
// Return Request
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "下载文件"

// ''' <summary>
// ''' 从FTP服务器下载文件，使用与远程文件同名的文件名来保存文件
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalPath">本地路径</param>
// Public Overloads Function Download(ByVal RemoteFileName As String, ByVal LocalPath As String) As Boolean Implements BaseFileService.Download
// Return Download(RemoteFileName, LocalPath, RemoteFileName)
// End Function
// '

// ''' <summary>
// ''' 从FTP服务器下载文件，指定本地路径和本地文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalPath">本地路径</param>
// ''' <param name="LocalFileName">保存本地的文件名</param>
// Public Overloads Function Download(ByVal RemoteFileName As String, ByVal LocalPath As String, ByVal LocalFileName As String) As Boolean
// Dim bt As Byte() = Nothing
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(LocalFileName) OrElse Not IsValidPathChars(LocalPath) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not Directory.Exists(LocalPath) Then
// Throw New Exception("本地文件路径不存在!")
// End If

// Dim LocalFullPath As String = Path.Combine(LocalPath, LocalFileName)
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If
// bt = Download(RemoteFileName)
// If bt IsNot Nothing Then
// Dim stream As New FileStream(LocalFullPath, FileMode.Create)
// stream.Write(bt, 0, bt.Length)
// stream.Flush()
// stream.Close()
// Return True
// Else
// Return False
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从FTP服务器下载文件，返回文件二进制数据
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Overloads Function Download(ByVal RemoteFileName As String) As Byte()
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// Response = Open(New Uri(Me.Host.ToString() & RemoteFileName), WebRequestMethods.Ftp.DownloadFile)
// Dim Reader As Stream = Response.GetResponseStream()

// Dim mem As New MemoryStream(1024 * 500)
// Dim buffer As Byte() = New Byte(1023) {}
// Dim bytesRead As Integer = 0
// Dim TotalByteRead As Integer = 0
// While True
// bytesRead = Reader.Read(buffer, 0, buffer.Length)
// TotalByteRead += bytesRead
// If bytesRead = 0 Then
// Exit While
// End If
// mem.Write(buffer, 0, bytesRead)
// End While
// If mem.Length > 0 Then
// Return mem.ToArray()
// Else
// Return Nothing
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "异步下载文件"
// '

// ''' <summary>
// ''' 从FTP服务器异步下载文件，指定本地路径和本地文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>        
// ''' <param name="LocalPath">保存文件的本地路径,后面带有"\"</param>
// ''' <param name="LocalFileName">保存本地的文件名</param>
// Public Overloads Sub DownloadAsync(ByVal RemoteFileName As String, ByVal LocalPath As String, ByVal LocalFileName As String)
// Dim bt As Byte() = Nothing
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(LocalFileName) OrElse Not IsValidPathChars(LocalPath) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not Directory.Exists(LocalPath) Then
// Throw New Exception("本地文件路径不存在!")
// End If

// Dim LocalFullPath As String = Path.Combine(LocalPath, LocalFileName)
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If

// Me.DownloadAsync(RemoteFileName, LocalFullPath)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// ''' <summary>
// ''' 从FTP服务器异步下载文件，指定本地完整路径文件名
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// ''' <param name="LocalFullPath">本地完整路径文件名</param>
// Public Overloads Sub DownloadAsync(ByVal RemoteFileName As String, ByVal LocalFullPath As String) Implements BaseFileService.DownloadAsync
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If File.Exists(LocalFullPath) Then
// Throw New Exception("当前路径下已经存在同名文件！")
// End If
// 'Dim client As New MyWebClient()
// 'AddHandler client.DownloadProgressChanged, New System.Net.DownloadProgressChangedEventHandler(AddressOf client_DownloadProgressChanged)
// 'AddHandler client.DownloadFileCompleted, New System.ComponentModel.AsyncCompletedEventHandler(AddressOf client_DownloadFileCompleted)
// Me.FtpWebClient.Credentials = New NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Me.FtpWebClient.Proxy = Me.Proxy
// End If
// Me.FtpWebClient.DownloadFileAsync(New Uri(Me.Host.ToString & RemoteFileName), LocalFullPath)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// Private Sub FtpWebClient_UploadProgressChanged(sender As Object, e As Net.UploadProgressChangedEventArgs) Handles FtpWebClient.UploadProgressChanged
// Dim info As New UploadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// info.m_BytesReceived = e.BytesReceived
// info.m_BytesSent = e.BytesSent
// info.m_ProgressPercentage = e.ProgressPercentage
// info.m_TotalBytesToReceive = e.TotalBytesToReceive
// info.m_TotalBytesToReceive = e.TotalBytesToReceive
// info.m_TotalBytesToSend = e.TotalBytesToSend
// RaiseEvent UploadProgressChanged(Me, info)
// End Sub
// Private Sub FtpWebClient_UploadDataCompleted(sender As Object, e As Net.UploadDataCompletedEventArgs) Handles FtpWebClient.UploadDataCompleted
// Dim info As New UploadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent UploadDataCompleted(Me, info)
// End Sub

// Private Sub FtpWebClient_UploadFileCompleted(sender As Object, e As Net.UploadFileCompletedEventArgs) Handles FtpWebClient.UploadFileCompleted
// Dim info As New UploadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent UploadDataCompleted(Me, info)
// End Sub

// Private Sub FtpWebClient_DownloadDataCompleted(sender As Object, e As Net.DownloadDataCompletedEventArgs) Handles FtpWebClient.DownloadDataCompleted
// Dim info As New DownloadDataCompletedEventArgs
// info._Cancelled = e.Cancelled
// info._Error = e.Error
// info._Result = e.Result
// info._UserState = e.UserState
// RaiseEvent DownloadDataCompleted(sender, info)
// End Sub

// ''' <summary>
// ''' 异步下载文件完成之后触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">数据信息对象</param>
// Private Sub client_DownloadFileCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs) Handles FtpWebClient.DownloadFileCompleted
// Dim Args As New AsyncCompletedEventArgs(e.Error, e.Cancelled, e.UserState)
// RaiseEvent DownloadFileCompleted(sender, Args)
// End Sub

// ''' <summary>
// ''' 异步下载进度发生改变触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">进度信息对象</param>
// Private Sub client_DownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs) Handles FtpWebClient.DownloadProgressChanged
// Dim Args As New DownloadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// Args.m_BytesReceived = e.BytesReceived
// Args.m_TotalBytesToReceive = e.TotalBytesToReceive
// RaiseEvent DownloadProgressChanged(sender, Args)
// End Sub

// ''' <summary>
// ''' 生成一个用HTTP GET方法访问指定图片大小的Uri
// ''' </summary>
// ''' <param name="FileName">文件服务器的文件名</param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Public Function GeneratePresignedUri(ByVal FileName As String, ByVal Width As Integer, ByVal Height As Integer) As Uri Implements BaseFileService.GeneratePresignedUri
// End Function
// #End Region

// #Region "上传文件"
// '
// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String) As Boolean
// Return Upload(LocalFullPath, Path.GetFileName(LocalFullPath), False)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal RemoteFileName As String) As Boolean Implements BaseFileService.Upload
// Return Me.Upload(LocalFullPath, RemoteFileName, False)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal OverWriteRemoteFile As Boolean) As Boolean
// Return Upload(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile)
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal LocalFullPath As String, ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(Path.GetFileName(LocalFullPath)) OrElse Not IsValidPathChars(Path.GetDirectoryName(LocalFullPath)) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If File.Exists(LocalFullPath) Then
// Dim Stream As New FileStream(LocalFullPath, FileMode.Open, FileAccess.Read)
// Dim bt As Byte() = New Byte(Stream.Length - 1) {}
// Stream.Read(bt, 0, CType(Stream.Length, Int32))
// '注意，因为Int32的最大限制，最大上传文件只能是大约2G多一点
// Stream.Close()
// Return Me.Upload(bt, RemoteFileName, OverWriteRemoteFile)
// Else
// Throw New Exception("本地文件不存在!")
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">上传的二进制数据</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Function Upload(ByVal FileBytes As Byte(), ByVal RemoteFileName As String) As Boolean
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// Return Upload(FileBytes, RemoteFileName, False)
// End Function
// '

// ''' <summary>
// ''' 上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">文件二进制内容</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Function Upload(ByVal FileBytes As Byte(), ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean) As Boolean

// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名！")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.UploadFile)
// Dim requestStream As Stream = Request.GetRequestStream
// Dim mem As New MemoryStream(FileBytes)

// Dim buffer As Byte() = New Byte(1023) {}
// Dim bytesRead As Integer = 0
// Dim TotalRead As Integer = 0
// While True
// bytesRead = mem.Read(buffer, 0, buffer.Length)
// If bytesRead = 0 Then
// Exit While
// End If
// TotalRead += bytesRead
// requestStream.Write(buffer, 0, bytesRead)
// End While
// requestStream.Close()
// Response = DirectCast(Request.GetResponse(), FtpWebResponse)
// mem.Close()
// mem.Dispose()
// FileBytes = Nothing
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "异步上传文件"
// '
// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String)
// UploadAsync(LocalFullPath, Path.GetFileName(LocalFullPath), False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal OverWriteRemoteFile As Boolean)
// UploadAsync(LocalFullPath, Path.GetFileName(LocalFullPath), OverWriteRemoteFile)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal RemoteFileName As String) Implements BaseFileService.UploadAsync
// UploadAsync(LocalFullPath, RemoteFileName, False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="LocalFullPath">本地带有完整路径的文件名</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal LocalFullPath As String, ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean)
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(Path.GetFileName(LocalFullPath)) OrElse Not IsValidPathChars(Path.GetDirectoryName(LocalFullPath)) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// If File.Exists(LocalFullPath) Then
// 'Dim client As New MyWebClient()

// 'AddHandler client.UploadProgressChanged, New System.Net.UploadProgressChangedEventHandler(AddressOf client_UploadProgressChanged)
// 'AddHandler client.UploadFileCompleted, New System.Net.UploadFileCompletedEventHandler(AddressOf client_UploadFileCompleted)
// 'client.Credentials = New System.Net.NetworkCredential(Me.UserName, Me.Password)
// 'If Me.Proxy IsNot Nothing Then
// '    client.Proxy = Me.Proxy
// 'End If
// 'Dim Uri As New Uri(Me.Host.ToString & RemoteFileName)
// 'client.UploadFileAsync(Uri, LocalFullPath)
// Me.FtpWebClient.Credentials = New System.Net.NetworkCredential(Me.UserName, Me.Password)
// If Me.Proxy IsNot Nothing Then
// Me.FtpWebClient.Proxy = Me.Proxy
// End If
// Dim Uri As New Uri(Me.Host.ToString & RemoteFileName)
// Me.FtpWebClient.UploadFileAsync(Uri, LocalFullPath)
// Else
// Throw New Exception("本地文件不存在!")
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">上传的二进制数据</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// Public Overloads Sub UploadAsync(ByVal FileBytes As Byte(), ByVal RemoteFileName As String)
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名或目录名!")
// End If
// UploadAsync(FileBytes, RemoteFileName, False)
// End Sub
// '

// ''' <summary>
// ''' 异步上传文件到FTP服务器
// ''' </summary>
// ''' <param name="FileBytes">文件二进制内容</param>
// ''' <param name="RemoteFileName">要在FTP服务器上面保存文件名</param>
// ''' <param name="OverWriteRemoteFile">是否覆盖远程服务器上面同名的文件</param>
// Public Overloads Sub UploadAsync(ByVal FileBytes As Byte(), ByVal RemoteFileName As String, ByVal OverWriteRemoteFile As Boolean)
// Try

// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("非法文件名！")
// End If
// If Not OverWriteRemoteFile AndAlso FileExist(RemoteFileName) Then
// Throw New Exception("FTP服务上面已经存在同名文件！")
// End If
// Dim TempPath As String = System.Environment.GetFolderPath(Environment.SpecialFolder.Templates)
// If Not TempPath.EndsWith("\") Then
// TempPath += "\"
// End If
// Dim TempFile As String = TempPath & Path.GetRandomFileName()
// TempFile = Path.ChangeExtension(TempFile, Path.GetExtension(RemoteFileName))
// Dim Stream As New FileStream(TempFile, FileMode.CreateNew, FileAccess.Write)
// Stream.Write(FileBytes, 0, FileBytes.Length)
// '注意，因为Int32的最大限制，最大上传文件只能是大约2G多一点
// Stream.Flush()
// Stream.Close()
// Stream.Dispose()
// _isDeleteTempFile = True
// _UploadTempFile = TempFile
// FileBytes = Nothing



// UploadAsync(TempFile, RemoteFileName, OverWriteRemoteFile)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Sub

// '

// ''' <summary>
// ''' 异步上传文件完成之后触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">数据信息对象</param>
// Private Sub client_UploadFileCompleted(ByVal sender As Object, ByVal e As System.Net.UploadFileCompletedEventArgs)
// If _isDeleteTempFile Then
// If File.Exists(_UploadTempFile) Then
// File.SetAttributes(_UploadTempFile, FileAttributes.Normal)
// File.Delete(_UploadTempFile)
// End If
// _isDeleteTempFile = False
// End If
// Dim args As New UploadFileCompletedEventArgs(e.Error, e.Cancelled, e.UserState)
// args.m_Result = e.Result
// RaiseEvent UploadFileCompleted(sender, args)
// End Sub

// '

// ''' <summary>
// ''' 异步上传进度发生改变触发的事件
// ''' </summary>
// ''' <param name="sender">下载对象</param>
// ''' <param name="e">进度信息对象</param>
// Private Sub client_UploadProgressChanged(ByVal sender As Object, ByVal e As System.Net.UploadProgressChangedEventArgs)
// Dim args As New UploadProgressChangedEventArgs(e.ProgressPercentage, e.UserState)
// args.m_BytesSent = e.BytesSent
// args.m_TotalBytesToReceive = e.TotalBytesToReceive
// args.m_TotalBytesToSend = e.TotalBytesToSend
// RaiseEvent UploadProgressChanged(sender, args)
// End Sub
// #End Region

// #Region "删除文件"
// ''' <summary>
// ''' 从FTP服务器上面删除一个文件
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Function Delete(ByVal RemoteFileName As String) As Boolean Implements BaseFileService.Delete
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("文件名非法！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.DeleteFile)
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// Return False
// End Try
// Return True
// End Function
// #End Region


// ''' <summary>
// ''' 生成一个用HTTP GET方法访问文件的Uri
// ''' </summary>
// ''' <param name="FileName">文件服务器的文件名</param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Public Function GeneratePresignedUri(ByVal FileName As String) As Uri Implements BaseFileService.GeneratePresignedUri
// Dim txt As String = Me.Host.OriginalString
// If txt.StartsWith("ftp://") Then
// txt = txt.Remove(0, 6)
// End If
// Return New Uri(String.Format("ftp://{0}:{1}@{2}/{3}", Me.UserName, Me.Password, txt, FileName))
// End Function

// #Region "列出目录文件信息"
// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有文件和目录
// ''' </summary>
// Public Function ListFilesAndDirectories() As FTPFileStruct()
// Response = Open(Me.Host, WebRequestMethods.Ftp.ListDirectoryDetails)
// Dim stream As New StreamReader(Response.GetResponseStream(), Me.Encoding)
// Dim Datastring As String = stream.ReadToEnd()
// Dim list As FTPFileStruct() = GetList(Datastring)
// Return list
// End Function
// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有文件
// ''' </summary>
// Public Function ListFiles() As FTPFileStruct()
// Dim listAll As FTPFileStruct() = ListFilesAndDirectories()
// Dim listFile As New List(Of FTPFileStruct)()
// For Each file As FTPFileStruct In listAll
// If Not file.IsDirectory Then
// listFile.Add(file)
// End If
// Next
// Return listFile.ToArray()
// End Function

// '

// ''' <summary>
// ''' 列出FTP服务器上面当前目录的所有的目录
// ''' </summary>
// Public Function ListDirectories() As FTPFileStruct()
// Dim listAll As FTPFileStruct() = ListFilesAndDirectories()
// Dim listDirectory As New List(Of FTPFileStruct)()
// For Each file As FTPFileStruct In listAll
// If file.IsDirectory Then
// listDirectory.Add(file)
// End If
// Next
// Return listDirectory.ToArray()
// End Function
// '

// ''' <summary>
// ''' 获得文件和目录列表
// ''' </summary>
// ''' <param name="datastring">FTP返回的列表字符信息</param>
// Private Function GetList(ByVal datastring As String) As FTPFileStruct()
// Dim myListArray As New List(Of FTPFileStruct)()
// Dim dataRecords As String() = datastring.Split(ControlChars.Lf)
// Dim _directoryListStyle As FTPListStyle = GuessFileListStyle(dataRecords)
// For Each s As String In dataRecords
// If _directoryListStyle <> FTPListStyle.Unknown AndAlso s <> "" Then
// Dim f As New FTPFileStruct()
// f.Name = ".."
// Select Case _directoryListStyle
// Case FTPListStyle.UnixStyle
// f = ParseFTPFileStructFromUnixStyleRecord(s)
// Exit Select
// Case FTPListStyle.WindowsStyle
// f = ParseFTPFileStructFromWindowsStyleRecord(s)
// Exit Select
// End Select
// If Not (f.Name = "." OrElse f.Name = "..") Then
// myListArray.Add(f)
// End If
// End If
// Next
// Return myListArray.ToArray()
// End Function

// '

// ''' <summary>
// ''' 从Windows格式中返回文件信息
// ''' </summary>
// ''' <param name="Record">文件信息</param>
// Private Function ParseFTPFileStructFromWindowsStyleRecord(ByVal Record As String) As FTPFileStruct
// Dim f As New FTPFileStruct()
// Dim processstr As String = Record.Trim()
// Dim dateStr As String = processstr.Substring(0, 8)
// processstr = (processstr.Substring(8, processstr.Length - 8)).Trim()
// Dim timeStr As String = processstr.Substring(0, 7)
// processstr = (processstr.Substring(7, processstr.Length - 7)).Trim()
// Dim myDTFI As DateTimeFormatInfo = New CultureInfo("en-US", False).DateTimeFormat
// myDTFI.ShortTimePattern = "t"
// f.CreateTime = DateTime.Parse(dateStr & " " & timeStr, myDTFI)
// If processstr.Substring(0, 5) = "<DIR>" Then
// f.IsDirectory = True
// processstr = (processstr.Substring(5, processstr.Length - 5)).Trim()
// Else
// 'Dim strs As String() = processstr.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
// ' true);
// Dim IndexOf As Integer = processstr.IndexOf(" ")
// processstr = processstr.Substring(IndexOf + 1)
// 'processstr = strs(1)
// f.IsDirectory = False
// End If
// f.Name = processstr
// Return f
// End Function

// ''' <summary>
// ''' 判断文件列表的方式Window方式还是Unix方式
// ''' </summary>
// ''' <param name="recordList">文件信息列表</param>
// Private Function GuessFileListStyle(ByVal recordList As String()) As FTPListStyle
// For Each s As String In recordList
// If s.Length > 10 AndAlso Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)") Then
// Return FTPListStyle.UnixStyle
// ElseIf s.Length > 8 AndAlso Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]") Then
// Return FTPListStyle.WindowsStyle
// End If
// Next
// Return FTPListStyle.Unknown
// End Function

// ''' <summary>
// ''' 从Unix格式中返回文件信息
// ''' </summary>
// ''' <param name="Record">文件信息</param>
// Private Function ParseFTPFileStructFromUnixStyleRecord(ByVal Record As String) As FTPFileStruct
// Dim f As New FTPFileStruct()
// Dim processstr As String = Record.Trim()
// f.Flags = processstr.Substring(0, 10)
// f.IsDirectory = (f.Flags(0) = "d"c)
// processstr = (processstr.Substring(11)).Trim()
// _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// '跳过一部分
// f.Owner = _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// f.Group = _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// _cutSubstringFromStringWithTrim(processstr, " "c, 0)
// '跳过一部分
// Dim yearOrTime As String = processstr.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)(2)
// If yearOrTime.IndexOf(":") >= 0 Then
// 'time
// processstr = processstr.Replace(yearOrTime, DateTime.Now.Year.ToString())
// End If
// f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(processstr, " "c, 8))
// f.Name = processstr
// '最后就是名称
// Return f
// End Function

// ''' <summary>
// ''' 按照一定的规则进行字符串截取
// ''' </summary>
// ''' <param name="s">截取的字符串</param>
// ''' <param name="c">查找的字符</param>
// ''' <param name="startIndex">查找的位置</param>
// Private Function _cutSubstringFromStringWithTrim(ByRef s As String, ByVal c As Char, ByVal startIndex As Integer) As String
// Dim pos1 As Integer = s.IndexOf(c, startIndex)
// Dim retString As String = s.Substring(0, pos1)
// s = (s.Substring(pos1)).Trim()
// Return retString
// End Function
// #End Region

// #Region "目录或文件存在的判断"

// ''' <summary>
// ''' 判断当前目录下指定的子目录是否存在
// ''' </summary>
// ''' <param name="RemoteDirectoryName">指定的目录名</param>
// Public Function DirectoryExist(ByVal RemoteDirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(RemoteDirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// Dim listDir As FTPFileStruct() = ListDirectories()
// For Each dir As FTPFileStruct In listDir
// If dir.Name = RemoteDirectoryName Then
// Return True
// End If
// Next
// Return False
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 判断一个远程文件是否存在服务器当前目录下面
// ''' </summary>
// ''' <param name="RemoteFileName">远程文件名</param>
// Public Function FileExist(ByVal RemoteFileName As String) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) Then
// Throw New Exception("文件名非法！")
// End If
// Dim listFile As FTPFileStruct() = ListFiles()
// For Each file As FTPFileStruct In listFile
// If file.Name = RemoteFileName Then
// Return True
// End If
// Next
// Return False
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region




// #Region "重命名文件"

// ''' <summary>
// ''' 更改一个文件的名称或一个目录的名称
// ''' </summary>
// ''' <param name="RemoteFileName">原始文件或目录名称</param>
// ''' <param name="NewFileName">新的文件或目录的名称</param>
// Public Function ReName(ByVal RemoteFileName As String, ByVal NewFileName As String) As Boolean
// Try
// If Not IsValidFileChars(RemoteFileName) OrElse Not IsValidFileChars(NewFileName) Then
// Throw New Exception("文件名非法！")
// End If
// If RemoteFileName = NewFileName Then
// Return True
// End If
// If FileExist(RemoteFileName) OrElse DirectoryExist(RemoteFileName) Then
// Request = OpenRequest(New Uri(Me.MergeHostAddress(RemoteFileName)), WebRequestMethods.Ftp.Rename)
// Request.RenameTo = NewFileName

// Response = DirectCast(Request.GetResponse(), FtpWebResponse)
// Else
// Throw New Exception("文件在服务器上不存在！")
// End If
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "拷贝、移动文件"

// ''' <summary>
// ''' 把当前目录下面的一个文件拷贝到服务器上面另外的目录中，注意，拷贝文件之后，当前工作目录还是文件原来所在的目录
// ''' </summary>
// ''' <param name="RemoteFile">当前目录下的文件名</param>
// ''' <param name="DirectoryName">新目录名称。
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ；
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// ''' <returns></returns>
// Public Function CopyFileToAnotherDirectory(ByVal RemoteFile As String, ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkDir As String = Me.RootDir
// Try
// Dim bt As Byte() = Download(RemoteFile)
// GotoDirectory(DirectoryName)
// Dim Success As Boolean = Upload(bt, RemoteFile, False)
// Me.RootDir = CurrentWorkDir
// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkDir
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 把当前目录下面的一个文件移动到服务器上面另外的目录中，注意，移动文件之后，当前工作目录还是文件原来所在的目录
// ''' </summary>
// ''' <param name="RemoteFile">当前目录下的文件名</param>
// ''' <param name="DirectoryName">新目录名称。
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ；
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// ''' <returns></returns>
// Public Function MoveFileToAnotherDirectory(ByVal RemoteFile As String, ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkDir As String = Me.RootDir
// Try
// If DirectoryName = "" Then
// Return False
// End If
// If Not DirectoryName.StartsWith("/") Then
// DirectoryName = "/" & DirectoryName
// End If
// If Not DirectoryName.EndsWith("/") Then
// DirectoryName += "/"
// End If
// Dim Success As Boolean = ReName(RemoteFile, DirectoryName & RemoteFile)
// Me.RootDir = CurrentWorkDir
// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkDir
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "建立、删除子目录"

// ''' <summary>
// ''' 在FTP服务器上当前工作目录建立一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Public Function MakeDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// If DirectoryExist(DirectoryName) Then
// Throw New Exception("服务器上面已经存在同名的文件名或目录名！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(DirectoryName)), WebRequestMethods.Ftp.MakeDirectory)
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录中删除一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Public Function RemoveDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法！")
// End If
// If Not DirectoryExist(DirectoryName) Then
// Throw New Exception("服务器上面不存在指定的文件名或目录名！")
// End If
// Response = Open(New Uri(Me.MergeHostAddress(DirectoryName)), WebRequestMethods.Ftp.RemoveDirectory)
// Return True
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function
// #End Region

// #Region "文件、目录名称有效性判断"

// ''' <summary>
// ''' 判断目录名中字符是否合法
// ''' </summary>
// ''' <param name="DirectoryName">目录名称</param>
// Public Function IsValidPathChars(ByVal DirectoryName As String) As Boolean
// Dim invalidPathChars As Char() = Path.GetInvalidPathChars()
// Dim DirChar As Char() = DirectoryName.ToCharArray()
// For Each C As Char In DirChar
// If Array.BinarySearch(invalidPathChars, C) >= 0 Then
// Return False
// End If
// Next
// Return True
// End Function

// ''' <summary>
// ''' 判断文件名中字符是否合法
// ''' </summary>
// ''' <param name="FileName">文件名称</param>
// Public Function IsValidFileChars(ByVal FileName As String) As Boolean
// Dim invalidFileChars As Char() = Path.GetInvalidFileNameChars()
// Dim NameChar As Char() = FileName.ToCharArray()
// For Each C As Char In NameChar
// If Array.BinarySearch(invalidFileChars, C) >= 0 Then
// Return False
// End If
// Next
// Return True
// End Function
// #End Region

// #Region "目录切换操作"

// ''' <summary>
// ''' 进入一个目录
// ''' </summary>
// ''' <param name="DirectoryName">
// ''' 新目录的名字。 
// ''' 说明：如果新目录是当前目录的子目录，则直接指定子目录。如: SubDirectory1/SubDirectory2 ； 
// ''' 如果新目录不是当前目录的子目录，则必须从根目录一级一级的指定。如： ./NewDirectory/SubDirectory1/SubDirectory2
// ''' </param>
// Public Function GotoDirectory(ByVal DirectoryName As String) As Boolean
// Dim CurrentWorkPath As String = Me.RootDir
// Try
// DirectoryName = DirectoryName.Replace("\", "/")
// Dim DirectoryNames As String() = DirectoryName.Split(New Char() {"/"c})
// If DirectoryNames(0) = "." Then
// Me.RootDir = "/"
// If DirectoryNames.Length = 1 Then
// Return True
// End If
// Array.Clear(DirectoryNames, 0, 1)
// End If
// Dim Success As Boolean = False
// For Each dir As String In DirectoryNames
// If dir IsNot Nothing Then
// Success = EnterOneSubDirectory(dir)
// If Not Success Then
// Me.RootDir = CurrentWorkPath
// Return False
// End If
// End If
// Next

// Return Success
// Catch ep As Exception
// Me.RootDir = CurrentWorkPath
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录进入一个子目录
// ''' </summary>
// ''' <param name="DirectoryName">子目录名称</param>
// Private Function EnterOneSubDirectory(ByVal DirectoryName As String) As Boolean
// Try
// If DirectoryName.IndexOf("/") >= 0 OrElse Not IsValidPathChars(DirectoryName) Then
// Throw New Exception("目录名非法!")
// End If
// If DirectoryName.Length > 0 AndAlso DirectoryExist(DirectoryName) Then
// If Not DirectoryName.EndsWith("/") Then
// DirectoryName += "/"
// End If
// m_RootDir += DirectoryName
// Return True
// Else
// Return False
// End If
// Catch ep As Exception
// ErrorMsg = ep.ToString()
// Throw ep
// End Try
// End Function

// ''' <summary>
// ''' 从当前工作目录往上一级目录
// ''' </summary>
// Public Function ComeoutDirectory() As Boolean
// If m_RootDir = "/" Then
// ErrorMsg = "当前目录已经是根目录！"
// Throw New Exception("当前目录已经是根目录！")
// End If
// Dim sp As Char() = New Char(0) {"/"c}

// Dim strDir As String() = m_RootDir.Split(sp, StringSplitOptions.RemoveEmptyEntries)
// If strDir.Length = 1 Then
// m_RootDir = "/"
// Else
// m_RootDir = [String].Join("/", strDir, 0, strDir.Length - 1)
// End If
// Return True
// End Function
// #End Region

// #Region "表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。"
// ''' <summary>
// ''' 表示要用于检索 FTP 服务器上的文件大小的 FTP SIZE 协议方法。
// ''' </summary>
// ''' <param name="FileName"></param>
// ''' <returns></returns>
// ''' <remarks></remarks>
// Friend Function GetFileSize(ByVal FileName As String) As Integer
// Dim ftp As FtpWebRequest
// Dim Uri As String = "ftp://" & Me.Host.Host & ":" & 21 & "/" & FileName
// ftp = DirectCast(FtpWebRequest.Create(New Uri(Uri)), FtpWebRequest)
// ftp.Credentials = New NetworkCredential(UserName, Password)
// ftp.Method = WebRequestMethods.Ftp.GetFileSize
// Dim Size As Integer
// Try
// Dim ftpresponse As FtpWebResponse = DirectCast(ftp.GetResponse(), FtpWebResponse)
// Size = ftpresponse.ContentLength
// Return Size
// Catch ex As WebException
// Dim wr As FtpWebResponse = DirectCast(ex.Response, FtpWebResponse)
// Catch ex As Exception
// Windows.Forms.MessageBox.Show(ex.ToString)
// End Try
// Return Size
// End Function
// #End Region

// '#Region "重载WebClient，支持FTP进度"
// '    Friend Class MyWebClient
// '        Inherits WebClient
// '        Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
// '            Dim req As FtpWebRequest = DirectCast(MyBase.GetWebRequest(address), FtpWebRequest)
// '            req.UsePassive = False
// '            Return req
// '        End Function
// '    End Class
// '#End Region

// End Class
